package services

import (
    "sync"
    "time"
    "volux/utils"
    "fmt"
)

type HealthService struct {
    mu              sync.RWMutex
    components      map[string]*ComponentHealth
    checkInterval   time.Duration
    alertService    *AlertService
}

type ComponentHealth struct {
    Name       string    `json:"name"`
    Status     string    `json:"status"` // healthy, degraded, failed
    LastCheck  time.Time `json:"last_check"`
    Message    string    `json:"message"`
    Checks     []Check   `json:"checks"`
}

type Check struct {
    Name     string `json:"name"`
    Status   string `json:"status"`
    Message  string `json:"message"`
}

func NewHealthService(alertService *AlertService) *HealthService {
    hs := &HealthService{
        components:    make(map[string]*ComponentHealth),
        checkInterval: time.Second * 30,
        alertService:  alertService,
    }
    
    // 注册组件
    hs.registerComponent("spdk", []string{"connection", "subsystems", "bdevs"})
    hs.registerComponent("etcd", []string{"connection", "leader", "storage"})
    
    go hs.monitor()
    return hs
}

func (hs *HealthService) registerComponent(name string, checks []string) {
    component := &ComponentHealth{
        Name:   name,
        Status: "unknown",
        Checks: make([]Check, len(checks)),
    }
    
    for i, check := range checks {
        component.Checks[i] = Check{Name: check, Status: "unknown"}
    }
    
    hs.components[name] = component
}

func (hs *HealthService) monitor() {
    ticker := time.NewTicker(hs.checkInterval)
    for range ticker.C {
        hs.checkHealth()
    }
}

func (hs *HealthService) checkHealth() {
    hs.mu.Lock()
    defer hs.mu.Unlock()

    for name, component := range hs.components {
        switch name {
        case "spdk":
            hs.checkSPDKHealth(component)
        case "etcd":
            hs.checkEtcdHealth(component)
        }
        
        component.LastCheck = time.Now()
        
        // 如果状态为failed，触发告警
        if component.Status == "failed" {
            hs.alertService.TriggerAlert(Alert{
                Type:     "COMPONENT_FAILURE",
                Level:    "critical",
                Message:  fmt.Sprintf("Component %s is down: %s", name, component.Message),
                Resource: name,
                Time:    time.Now(),
                Status:  "active",
            })
        }
    }
}

func (hs *HealthService) checkSPDKHealth(component *ComponentHealth) {
    spdkClient := utils.GetSPDKClient()
    if spdkClient == nil {
        component.Status = "failed"
        component.Message = "SPDK client not available"
        return
    }

    // 检查各项指标
    // ...
}

func (hs *HealthService) checkEtcdHealth(component *ComponentHealth) {
    etcdClient := utils.GetEtcdClient()
    if etcdClient == nil {
        component.Status = "failed"
        component.Message = "Etcd client not available"
        return
    }

    // 检查集群状态
    // ...
}

func (hs *HealthService) GetHealth() map[string]*ComponentHealth {
    hs.mu.RLock()
    defer hs.mu.RUnlock()
    
    return hs.components
}
